package ranab.jar.view;

import java.util.Vector;
import java.util.Date;
import java.util.Collections;
import java.util.zip.ZipEntry;
import java.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import ranab.gui.GuiUtils;
import ranab.jar.*;

/**
 * This is the table model to display Jar file.
 * 
 * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
 */
public 
class JarTable extends AbstractTableModel
               implements JarObserver, JarUI {

    private final static SimpleDateFormat mFormatter = new SimpleDateFormat ("dd,MMM,yy HH:mm");

    public final static ZipComparator[] mHeader = {
        new ZipNameComparator(), 
        new ZipSizeComparator(), 
        new ZipCompressedSizeComparator(), 
        new ZipModificationTimeComparator(), 
        new ZipPathComparator()
    };


    private Vector mTabelData = null;

    private Component mParent;
    private JTable mjTable;
	
	private JPanel mjTopPane;
	private JComboBox mjAscCombo;
	private JComboBox mjDesCombo;
	
	private boolean mbIsActive;
	
	
    /**
     * Initialize the table model
     */
    public JarTable(Component parent) {
        mTabelData = new Vector();
        mParent = parent;
		mbIsActive = false;
        initComponents();
    }

	/**
	 * Init UI components
	 */
	private void initComponents()  {
		mjTable = new JTable(this);
        mjTable.setColumnSelectionAllowed(false);
        mjTable.setBackground(Color.white);
		
		JScrollPane scrollPane = new JScrollPane(mjTable, 
									JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                               		JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		mjTopPane = new JPanel();
		mjTopPane.setLayout(new BorderLayout());
		mjTopPane.add(scrollPane, BorderLayout.CENTER);
		mjTopPane.add(getComboPanel(), BorderLayout.NORTH);
	}
	
	/**
	 * Create sort combo panel.
	 */
	private JPanel getComboPanel()  {
	
		JPanel ascPanel = new JPanel();
		JLabel ascLabel = new JLabel("Ascending Sorting");
		ascLabel.setForeground (Color.black);
        ascLabel.setHorizontalAlignment (SwingConstants.CENTER);
        ascLabel.setFont (new Font ("Serif", 1, 14));
		mjAscCombo = new JComboBox(JarTable.mHeader);
		mjAscCombo.addActionListener(
			new ActionListener()  {
				public void actionPerformed(ActionEvent e)  {
					ZipComparator comp = (ZipComparator)mjAscCombo.getSelectedItem();
					sortColumn(comp, true);
				}
			}
		);
		ascPanel.add(ascLabel);
		ascPanel.add(mjAscCombo);
		
		JPanel desPanel = new JPanel();
		JLabel desLabel = new JLabel("Descending Sorting");
		desLabel.setForeground (Color.black);
        desLabel.setHorizontalAlignment (SwingConstants.CENTER);
        desLabel.setFont (new Font ("Serif", 1, 14));
		mjDesCombo = new JComboBox(JarTable.mHeader);
		mjDesCombo.addActionListener(
			new ActionListener()  {
				public void actionPerformed(ActionEvent e)  {
					ZipComparator comp = (ZipComparator)mjDesCombo.getSelectedItem();
					sortColumn(comp, false);
				}
			}
		);
		desPanel.add(desLabel);
		desPanel.add(mjDesCombo);
		
		JPanel topPane = new JPanel();
	    topPane.setLayout(new FlowLayout(FlowLayout.CENTER));
		topPane.add(ascPanel);
		topPane.add(desPanel);
		return topPane;
	}
	
	
    // TableModel implementation
    /**
     * Get the number of columns.
     */
    public int getColumnCount() {
        return mHeader.length;
    }

    /**
     * Get column name.
     */
    public String getColumnName(int index) {
        return mHeader[index].getHeaderName();
    }

    /**
     * Get column class.
     */
    public Class getColumnClass(int columnIndex) {
        switch (columnIndex) {
        case 0:
            return String.class;

        case 1:
            return Long.class;

        case 2:
            return Long.class;

        case 3:
            return String.class;

        case 4:
            return String.class;

        default:
            return String.class;
        }
    }

    /**
     * Cell is not editable in this table.
     */
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    /**
     * Get the number of rows.
     */
    public int getRowCount() {
        return mTabelData.size();
    }

    /**
     * Get cell value.
     */
    public Object getValueAt(int rowIndex, int columnIndex) {
        ZipEntry ze = (ZipEntry)mTabelData.elementAt(rowIndex);
        switch (columnIndex) {
        case 0: 
            return ZipNameComparator.getName(ze);

        case 1:
            return new Long(ze.getSize());

        case 2:
            return new Long(ze.getCompressedSize());

        case 3:
            return mFormatter.format(new Date(ze.getTime()));

        case 4:
            return ZipPathComparator.getPath(ze);

        default:
            return null;
        }
    }

    // MyJarObserver implementation
    /**
     * Start viewing - clear the old data
     */
    public void start() {
        int sz = mTabelData.size();
        if (sz != 0) {
            mTabelData.clear();
            fireTableRowsDeleted(0, sz-1);
        }
    }

    /**
     * Set count - ignore.
     */
    public void setCount(int count) {
    }

    /**
     * Next entry found.
     */
    public void setNext(ZipEntry je) {
        int row = mTabelData.size();
        if (!je.isDirectory()) {
            mTabelData.add(je);
            fireTableRowsInserted(row, row);
        }
    }

    /**
     * Error messgae.
     */
    public void setError(String errMsg) {
		if (isActive())  {
        	GuiUtils.showErrorMessage(mParent, errMsg);
		}
    }  

    /**
     * End viewing - ignore.
     */
    public void end() {
    }

	/**
     * Update component UI.
     */
    public void updateLnF() {
		SwingUtilities.updateComponentTreeUI(mjTopPane);
    }
	
    /**
     * Get the scroll pane that contains the table.
     */
    public JPanel getPanel() {
        return mjTopPane;
    }
	
	
	/**
	 * Is active
	 */
	public boolean isActive()  {
		return mbIsActive;
	}
	
	/**
	 * Set enable tag.
	 */
	public void setActive(boolean b)  {
		mbIsActive = b;
	}
	
    /**
     * Returns the selected zip entries.
     */
    public ZipEntry[] getSelectedEntries() {
        int indices[] = mjTable.getSelectedRows();
        if (indices.length == 0) {
            return null;
        }

        ZipEntry entries[] = new ZipEntry[indices.length];
        for (int i=0; i<entries.length; i++) {
            entries[i] = (ZipEntry)mTabelData.elementAt(indices[i]);
        }
        return entries;
    }
	
    /**
     * Sort column.
     */
    public void sortColumn(ZipComparator comp, boolean asc)  {

        if (comp == null) {
            return;
        }

        ZipComparator finalComp = null;
        if (asc) {
            finalComp = comp;
        } else {
            finalComp = new ZipReverseComparator(comp);
        }
        Collections.sort(mTabelData, finalComp);
        fireTableDataChanged();
    }

} 
